package com.c.ctgproject.ui.files

import android.app.Activity
import android.app.ProgressDialog
import android.content.ContentResolver
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.database.Cursor
import android.net.Uri
import android.os.Environment
import android.provider.MediaStore
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.c.ctgproject.R
import com.c.ctgproject.base.BaseActivity
import com.c.ctgproject.customview.GlideImageLoader
import com.c.ctgproject.customview.ImagePickerLoader
import com.c.ctgproject.entity.OldPhotoVideoEntity
import com.c.ctgproject.entity.ResultEntity
import com.c.ctgproject.utils.*
import com.c.ctgproject.utils.photovideo.videocompressor.VideoCompress
import com.c.ctgproject.wiget.dialog.VideoShowDialog
import com.lwkandroid.imagepicker.ImagePicker
import com.lwkandroid.imagepicker.data.ImageBean
import com.lwkandroid.imagepicker.data.ImagePickType
import com.lwkandroid.widget.ninegridview.NineGirdImageContainer
import com.lwkandroid.widget.ninegridview.NineGridBean
import com.lwkandroid.widget.ninegridview.NineGridView
import com.nanchen.compresshelper.CompressHelper
import com.xiao.nicevideoplayer.NiceVideoPlayerManager
import com.zhihu.matisse.Matisse
import com.zhihu.matisse.MimeType
import com.zhihu.matisse.engine.impl.GlideEngine
import com.zhihu.matisse.internal.entity.CaptureStrategy
import kotlinx.android.synthetic.main.activity_file_upload_photo_video.*
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.File


/**
 *作者:LiBW
 *创建日期: 2020/9/16
 *描述:档案部 上传图片和视频页面
 */
class FileUploadPhotoVideoActivity : BaseActivity() {
    private val mViewModel: FileUploadPhotoVideoViewModel by lazy { ViewModelProvider(this)[FileUploadPhotoVideoViewModel::class.java] }
    private val requestCodePicker = 1001

    //视频选择器请求码
    private val requestCodeChoose = 1002

    //视频展示列表
    private val videoShowList = ArrayList<String>()
    private val imageShowList = ArrayList<String>()

    /***所有地址中 不包含OSS的视频(等待处理的视频)*/
    private val videoPaths: ArrayList<String> = ArrayList()

    //已经处理过的图片地址
    private val imageFiles: ArrayList<File> = ArrayList()

    //压缩后的视频地址
    private val newVideoPaths: ArrayList<String> = ArrayList()
    private val deleteUrl = ArrayList<String>()
    private val carCode: String by lazy { intent.getStringExtra("carCode") }
    override fun getLayout() = R.layout.activity_file_upload_photo_video

    //文件上传中标志位
    private var uploadingFlag = false

    override fun event() {
        changeTransparentStatusBar()
        init()
        MyLog.d("过来的carCode:$carCode")
        //图片视频上传回调
        mViewModel.upPhoto.observe(this, Observer {
            uploadingFlag = false
            MyLog.d("文件上传接口回调信息$it")
            loading.dismiss()
            if (it == null) return@Observer
            val data = getGson().fromJson(it, ResultEntity::class.java)
            if (data.status == 0) {
                //图片视频上传成功
                showToast(data.msg)
                finish()
            } else {
                CustomToast.showToast(this, data.msg.toString())
                MyLog.d("图片上传失败${data.msg}")
            }
        })
        mViewModel.error.observe(this, Observer {
            uploadingFlag = false
            loading.dismiss()
            showToast(it)
        })
        loading.show()
        mViewModel.getOldPhotoVideo(carCode)
        //上次传入的图片和视频
        mViewModel.oldPhoto.observe(this, Observer {
            loading.dismiss()
            MyLog.d("旧数据$it")
            val data = initData(it)
            if (data.status == 0) {
                val entity = getGson().fromJson(it, OldPhotoVideoEntity::class.java).data
                entity?.picture?.let { image ->
                    val mList = ArrayList<NineGridBean>()
                    image.forEach { i ->
                        mList.add(NineGridBean(i.picUrl))
                        i.picUrl?.let { url ->
                            imageShowList.add(url)
                        }
                    }
                    mPhotoNGV.addDataList(mList)
                }
                entity?.video?.let { video ->
                    val videoList = ArrayList<String>()
                    val mList = ArrayList<NineGridBean>()
                    video.forEach { v ->
                        videoList.add(v.videoUrl.handlerNull())
                        v.videoUrl?.let { url ->
                            videoShowList.add(url)
                        }
                        mList.add(NineGridBean(v.videoUrl))
                    }
                    mVideoNGV.addDataList(mList)
                }
            } else {
                showToast(data.msg)
            }
        })
    }


    override fun click() {
        mConfirmBTN.setOnClickListener { _ ->
            if (uploadingFlag) return@setOnClickListener
            uploadingFlag = true
            imageFiles.clear()
            videoShowList.forEach {
                if (!it.startsWith("http")) {
                    MyLog.d("出错的URL:$it")
                    videoPaths.add(it)
                }
            }
            imageShowList.forEach {
                if (!it.startsWith("http")) {
                    val file = File(it)
                    val newFile: File = CompressHelper.getDefault(this).compressToFile(file)
                    imageFiles.add(newFile)
                }
            }
            if (imageFiles.size == 0 && videoPaths.size == 0 && deleteUrl.size == 0) {
                showToast("无变化")
            } else {
                handlerVideo()
            }
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == requestCodePicker && resultCode == Activity.RESULT_OK && data != null) {
            val list: List<ImageBean> = data.getParcelableArrayListExtra(ImagePicker.INTENT_RESULT_DATA)
            val resultList: MutableList<NineGridBean> = java.util.ArrayList()
            for (imageBean in list) {
                val nineGirdData = NineGridBean(imageBean.imagePath)
//                if (imageBean.imageId==null||imageBean.imageId=="null"||imageBean.imageId.isEmpty()){
//                    MyLog.d("我发现你是新照片")
//                    //将新拍照片存入相册
//                    MediaStore.Images.Media.insertImage(contentResolver,imageBean.imagePath,imageBean.imagePath,null);
//                }
                imageShowList.add(imageBean.imagePath)
                resultList.add(nineGirdData)
            }
            mPhotoNGV.addDataList(resultList)
        }

        if (requestCode == requestCodeChoose && resultCode == Activity.RESULT_OK && data != null) {
            //图片路径 同样视频地址也是这个 根据requestCode
            val mSelected = Matisse.obtainResult(data)
            val resultList: MutableList<NineGridBean> = java.util.ArrayList()
            MyLog.d("视频地址uri列表:$mSelected")
            mSelected.forEach {
                val filePath = getRealFilePath(this, it)
                //列表中视频的地址
                val nineGirdData = NineGridBean(filePath)
                filePath?.let { path ->
                    videoShowList.add(path)
                }
                resultList.add(nineGirdData)
            }
            mVideoNGV.addDataList(resultList)
        }
    }


    private fun init() {
        //设置图片加载器，这个是必须的，不然图片无法显示
        mPhotoNGV.setImageLoader(GlideImageLoader())
        //设置显示列数，默认3列
        mPhotoNGV.setColumnCount(3)
        //设置是否为编辑模式，默认为false
        mPhotoNGV.setIsEditMode(true)
        //设置单张图片显示时的尺寸，默认100dp
        mPhotoNGV.setSingleImageSize(150)
        //设置单张图片显示时的宽高比，默认1.0f
        mPhotoNGV.setSingleImageRatio(0.8f)
        //设置最大显示数量，默认9张
        mPhotoNGV.setMaxNum(5)
        //设置图片显示间隔大小，默认3dp
        mPhotoNGV.setSpcaeSize(4)
        //设置删除图片
        //        mNineGridView.setIcDeleteResId(R.drawable.ic_block_black_24dp);
        //设置删除图片与父视图的大小比例，默认0.25f
        //设置删除图片
        //        mNineGridView.setIcDeleteResId(R.drawable.ic_block_black_24dp);
        //设置删除图片与父视图的大小比例，默认0.25f
        mPhotoNGV.setRatioOfDeleteIcon(0.15f)
        //设置“+”号的图片
        mPhotoNGV.setIcAddMoreResId(R.drawable.ic_ngv_add_pic)
        //设置各类点击监听
        mPhotoNGV.setOnItemClickListener(object : NineGridView.onItemClickListener {
            override fun onNineGirdItemDeleted(position: Int, gridBean: NineGridBean?, imageContainer: NineGirdImageContainer?) {
                if (imageShowList.isNotEmpty()) {
                    imageShowList.removeAt(position)
                }
                //如果移除的url是OSS内的则发送给后端删除
                gridBean?.originUrl?.let {
                    if (it.startsWith("http")) {
                        deleteUrl.add(it)
                    }
                }
            }

            override fun onNineGirdItemClick(position: Int, gridBean: NineGridBean?, imageContainer: NineGirdImageContainer?) {

            }

            override fun onNineGirdAddMoreClick(cha: Int) {
                //编辑模式下，图片展示数量尚未达到最大数量时，会显示一个“+”号，点击后回调这里
//                val galleryPath = (Environment.getExternalStorageDirectory()
//                    .toString() + File.separator + Environment.DIRECTORY_DCIM
//                        + File.separator + "Camera" + File.separator)
                val imageLoader = ImagePicker()
                    .cachePath(Environment.getExternalStorageDirectory().absolutePath)
//                    .cachePath(galleryPath)
                    .pickType(ImagePickType.MULTI)
                    .displayer(ImagePickerLoader())
                    .maxNum(cha)
                    .start(this@FileUploadPhotoVideoActivity, requestCodePicker)
            }
        })
        //设置图片加载器，这个是必须的，不然图片无法显示
        mVideoNGV.setImageLoader(GlideImageLoader())
        //设置显示列数，默认3列
        mVideoNGV.setColumnCount(3)
        //设置是否为编辑模式，默认为false
        mVideoNGV.setIsEditMode(true)
        //设置单张图片显示时的尺寸，默认100dp
        mVideoNGV.setSingleImageSize(150)
        //设置单张图片显示时的宽高比，默认1.0f
        mVideoNGV.setSingleImageRatio(0.8f)
        //设置最大显示数量，默认9张
        mVideoNGV.setMaxNum(2)
        //设置图片显示间隔大小，默认3dp
        mVideoNGV.setSpcaeSize(4)
        //设置删除图片
        //        mNineGridView.setIcDeleteResId(R.drawable.ic_block_black_24dp);
        //设置删除图片与父视图的大小比例，默认0.25f
        //设置删除图片
        //        mNineGridView.setIcDeleteResId(R.drawable.ic_block_black_24dp);
        //设置删除图片与父视图的大小比例，默认0.25f
        mVideoNGV.setRatioOfDeleteIcon(0.15f)
        //设置“+”号的图片
        mVideoNGV.setIcAddMoreResId(R.drawable.icon_add_video)
        //设置各类点击监听
        mVideoNGV.setOnItemClickListener(object : NineGridView.onItemClickListener {
            override fun onNineGirdItemDeleted(position: Int, gridBean: NineGridBean?, imageContainer: NineGirdImageContainer?) {
                if (videoShowList.isNotEmpty()) {
                    videoShowList.removeAt(position)
                }
                //如果移除的url是OSS内的则发送给后端删除
                gridBean?.originUrl?.let {
                    if (it.startsWith("http")) {
                        deleteUrl.add(it)
                    }
                }
            }

            override fun onNineGirdItemClick(position: Int, gridBean: NineGridBean?, imageContainer: NineGirdImageContainer?) {
                //使用dialog展示视频
                gridBean?.originUrl?.let {
                    val dialog = VideoShowDialog(it)
                    dialog.show(supportFragmentManager, "video")
                }
            }

            override fun onNineGirdAddMoreClick(cha: Int) {
                //编辑模式下，图片展示数量尚未达到最大数量时，会显示一个“+”号，点击后回调这里
                val videoPicker =  //视频选择器
                    Matisse.from(this@FileUploadPhotoVideoActivity)
                        .choose(MimeType.ofVideo())
                        //是否只显示选择的类型的缩略图，就不会把所有图片视频都放在一起，而是需要什么展示什么
                        .showSingleMediaType(true)
                        //这两行要连用 是否在选择图片中展示照相 和适配安卓7.0 FileProvider
                        .capture(true)
                        .captureStrategy(CaptureStrategy(true, "com.ctgoe.paoding.gq.fileProvider"))
                        //有序选择图片 123456...
                        .countable(true)
                        //最大选择数量为9
                        .maxSelectable(2)
                        //选择方向
                        .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
                        //界面中缩略图的质量
                        .thumbnailScale(0.8f)
                        //蓝色主题
                        .theme(R.style.Matisse_Zhihu)
                        //黑色主题
                        .theme(R.style.Matisse_Dracula)
                        //Glide加载方式
                        .imageEngine(GlideEngine())
                        //请求码
                        .forResult(requestCodeChoose)
            }
        })
    }


    private fun uri2File(uri: Uri): File {
        //uri转换成file
        val arr = arrayOf(MediaStore.Images.Media.DATA)
        val cursor = managedQuery(uri, arr, null, null, null)
        val imgIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
        cursor.moveToFirst()
        val imgPath = cursor.getString(imgIndex)
        return File(imgPath)
    }


    private fun getRealFilePath(context: Context, uri: Uri?): String? {
        if (null == uri) return null
        val scheme = uri.scheme
        var data: String? = null
        when {
            scheme == null -> data = uri.path
            ContentResolver.SCHEME_FILE == scheme -> {
                data = uri.path
            }
            ContentResolver.SCHEME_CONTENT == scheme -> {
                val cursor: Cursor = context.contentResolver.query(uri, arrayOf<String>(MediaStore.Images.ImageColumns.DATA), null, null, null)!!
                if (cursor.moveToFirst()) {
                    val index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA)
                    if (index > -1) {
                        data = cursor.getString(index)
                    }
                }
                cursor.close()
            }
        }
        return data
    }

    private var handlerCount = 0

    //压缩视频
    private fun handlerVideo() {
        MyLog.d("需要压缩的视频数量${videoPaths.size}")
        if (videoPaths.size == 0) {
            //没有视频将其他上传给服务器
            upDataToHttp()
        } else {
            handlerCount = videoPaths.size
            newVideoPaths.clear()
            MyLog.d("处理视频的方法")
            val dialog = ProgressDialog(this, R.style.AppTheme_Dark_Dialog)
            dialog.isIndeterminate = true
            dialog.setCanceledOnTouchOutside(false)
            dialog.setCancelable(true)
            dialog.setMessage("正在压缩视频")
            dialog.show()
            for (i in 0 until videoPaths.size) {
                val newPath = "${externalCacheDir}${i}.mp4"
                newVideoPaths.add(newPath)
                MyLog.d("视频地址$newPath")
                VideoCompress.compressVideoLow(videoPaths[i], newPath, object : VideoCompress.CompressListener {
                    override fun onSuccess() {
                        handlerCount--
                        if (handlerCount == 0) {
                            //图片处理完毕上传给服务器
                            upDataToHttp()
                            dialog.dismiss()
                        }
                    }

                    override fun onFail() {
                    }

                    override fun onProgress(percent: Float) {
                        MyLog.d("进度$percent")
                    }

                    override fun onStart() {
                    }
                })
            }
        }
    }

    private fun upDataToHttp() {
        val newVideoFiles = ArrayList<File>()
        newVideoPaths.forEach {
            val file = File(it)
            newVideoFiles.add(file)
        }
        loading.show()
        mViewModel.upPhotoAndVideo(userToken, filesToMultipartBodyParts(imageFiles, newVideoFiles))
    }

    private fun filesToMultipartBodyParts(pictureFile: ArrayList<File>, videoFile: ArrayList<File>): ArrayList<MultipartBody.Part> {
        val parts: ArrayList<MultipartBody.Part> = ArrayList()
        for (i in pictureFile) {
            MyLog.d("上传文华图片的名字${i.name}")
            toRequestBodyOfImage("img", i)?.let { parts.add(it) }
        }

        MyLog.d("传给文华的视频:${videoFile.size}")
        videoFile.forEach { file ->
            MyLog.d("传给文华的视频:${file.name}")
            toRequestBodyOfImage("video", file)?.let { parts.add(it) }
        }
        MyLog.d("carCode:$carCode")
        toRequestBodyOfText("carCode", carCode)?.let { parts.add(it) }
        deleteUrl.forEach { url ->
            toRequestBodyOfText("oldUrl", url)?.let { parts.add(it) }
        }
        MyLog.d("上传删除的URL:$deleteUrl")
        return parts
    }

    private fun toRequestBodyOfImage(keyStr: String, pFile: File): MultipartBody.Part? {
        val requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), pFile)
        return MultipartBody.Part.createFormData(keyStr, pFile.name, requestBody)
    }

    private fun toRequestBodyOfText(keyStr: String, value: String): MultipartBody.Part? {
        return MultipartBody.Part.createFormData(keyStr, value)
    }

    override fun onDestroy() {
        super.onDestroy()
        NiceVideoPlayerManager.instance().releaseNiceVideoPlayer()
    }

    override fun onBackPressed() {
        if (NiceVideoPlayerManager.instance().onBackPressd()) return
        super.onBackPressed()
    }
}